





import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
import numpy as np





train_data = pd.read_csv("../../RawData/train.csv")
test_data = pd.read_csv("../../RawData/test.csv")






# 将 PassengerId 和 Name 从 train_data 和 test_data 中剔除
deleted_cols = ['PassengerId', 'Name']
train_data.drop(columns=deleted_cols, inplace=True)
test_data.drop(columns=deleted_cols, inplace=True)


# 将服务费用类的属性填补为均值
numeric_cols = ['RoomService', 'FoodCourt', 'ShoppingMall', 'Spa', 'VRDeck']
for numeric_col in numeric_cols:
    train_data[numeric_col].fillna(train_data[numeric_col].mean(), inplace=True)
    test_data[numeric_col].fillna(train_data[numeric_col].mean(), inplace=True)


# 将年龄填补为中位数 （中位数适用于偏态分布）
train_data['Age'].fillna(train_data['Age'].median(), inplace=True)
test_data['Age'].fillna(train_data['Age'].median(), inplace=True)


# 将布尔值类型的属性映射为 0 和 1，并且将缺省值填补为 0
# 对训练集进行操作
train_bool_cols = ['CryoSleep', 'VIP', 'Transported']
for col in train_bool_cols:
    train_data[col].fillna(False, inplace=True)
# 对测试集合进行操作，测试集中没有 Transported 列
test_bool_cols = ['CryoSleep', 'VIP']
for col in test_bool_cols:
    test_data[col].fillna(False, inplace=True)


# 将分类列的缺省值填补为众数，再编码为 one-hot-code
categorical_cols = ['HomePlanet', 'Destination']
# 填补缺省值为众数
for categorical_col in categorical_cols:
    train_data[categorical_col] = train_data[categorical_col].fillna(train_data[categorical_col].mode()[0])
    test_data[categorical_col] = test_data[categorical_col].fillna(test_data[categorical_col].mode()[0])
# 编码为 one-hot-code
train_data = pd.get_dummies(train_data, columns=categorical_cols)
test_data = pd.get_dummies(test_data, columns=categorical_cols)


# 将carbin拆分成 Deck, Room, Side 三个列，再分别量化
train_data[['Deck', 'Room', 'Side']] = train_data['Cabin'].str.split('/', expand=True)
test_data[['Deck', 'Room', 'Side']] = test_data['Cabin'].str.split('/', expand=True)


# 将 Deck 的缺省值填补为众数，量化 Deck
label_encoder = LabelEncoder()
# 先将缺省值填补为众数
train_data['Deck'].fillna(train_data['Deck'].mode()[0], inplace=True)
test_data['Deck'].fillna(test_data['Deck'].mode()[0], inplace=True)
# 通过 label_encoder 量化 Deck
train_data['Deck'] = label_encoder.fit_transform(train_data['Deck'])
test_data['Deck'] = label_encoder.fit_transform(test_data['Deck'])


# 量化 Room，用众数补全缺省值
train_data['Room'] = pd.to_numeric(train_data['Room'], errors='coerce').fillna(train_data['Room'].mode()[0])
train_data['Room'] = train_data['Room'].astype(int)
test_data['Room'] = pd.to_numeric(test_data['Room'], errors='coerce').fillna(test_data['Room'].mode()[0])
test_data['Room'] = test_data['Room'].astype(int)


# 量化 Side，将缺省值填充为 0
train_data['Side'] = train_data['Side'].map({'S':0, 'P': 1}).fillna(0).astype(bool)
test_data['Side'] = test_data['Side'].map({'S':0, 'P': 1}).fillna(0).astype(bool)


# 删除原始属性 carbin
train_data.drop(columns=['Cabin'], inplace=True)
test_data.drop(columns=['Cabin'], inplace=True)


print(train_data)











# 计算上下限
train_Age_Q1 = train_data['Age'].quantile(0.25)
train_Age_Q3 = train_data['Age'].quantile(0.75)
train_Age_IQR = train_Age_Q1 - train_Age_Q3
train_Age_lower_bound = train_Age_Q1 - 1.5 * train_Age_IQR
train_Age_upper_bound = train_Age_Q3 + 1.5 * train_Age_IQR
# 将检测到的异常值替换为边界值
train_data['Age'] = np.clip(train_data['Age'], train_Age_lower_bound, train_Age_upper_bound)





test_Age_Q1 = test_data['Age'].quantile(0.25)
test_Age_Q3 = test_data['Age'].quantile(0.75)
test_Age_IQR = test_Age_Q1 - test_Age_Q3
test_Age_lower_bound = test_Age_Q1 - 1.5 * test_Age_IQR
test_Age_upper_bound = test_Age_Q3 + 1.5 * test_Age_IQR
# 将检测到的异常值替换为边界值
test_data['Age'] = np.clip(test_data['Age'], test_Age_lower_bound, test_Age_upper_bound)








train_RoomService_Q1 = train_data['RoomService'].quantile(0.25)
train_RoomService_Q3 = train_data['RoomService'].quantile(0.75)
train_RoomService_IQR = train_RoomService_Q1 - train_RoomService_Q3
train_RoomService_lower_bound = train_RoomService_Q1 - 1.5 * train_RoomService_IQR
train_RoomService_upper_bound = train_RoomService_Q3 + 1.5 * train_RoomService_IQR
# 将检测到的异常值替换为边界值
train_data['RoomService'] = np.clip(train_data['RoomService'], train_RoomService_lower_bound, train_RoomService_upper_bound)





test_RoomService_Q1 = test_data['RoomService'].quantile(0.25)
test_RoomService_Q3 = test_data['RoomService'].quantile(0.75)
test_RoomService_IQR = test_RoomService_Q1 - test_RoomService_Q3
test_RoomService_lower_bound = test_RoomService_Q1 - 1.5 * test_RoomService_IQR
test_RoomService_upper_bound = test_RoomService_Q3 + 1.5 * test_RoomService_IQR
# 将检测到的异常值替换为边界值
test_data['RoomService'] = np.clip(test_data['RoomService'], test_RoomService_lower_bound, test_RoomService_upper_bound)








train_FoodCourt_Q1 = train_data['FoodCourt'].quantile(0.25)
train_FoodCourt_Q3 = train_data['FoodCourt'].quantile(0.75)
train_FoodCourt_IQR = train_FoodCourt_Q1 - train_FoodCourt_Q3
train_FoodCourt_lower_bound = train_FoodCourt_Q1 - 1.5 * train_FoodCourt_IQR
train_FoodCourt_upper_bound = train_FoodCourt_Q3 + 1.5 * train_FoodCourt_IQR
# 将检测到的异常值替换为边界值
train_data['FoodCourt'] = np.clip(train_data['FoodCourt'], train_FoodCourt_lower_bound, train_FoodCourt_upper_bound)





test_FoodCourt_Q1 = test_data['FoodCourt'].quantile(0.25)
test_FoodCourt_Q3 = test_data['FoodCourt'].quantile(0.75)
test_FoodCourt_IQR = test_FoodCourt_Q1 - test_FoodCourt_Q3
test_FoodCourt_lower_bound = test_FoodCourt_Q1 - 1.5 * test_FoodCourt_IQR
test_FoodCourt_upper_bound = test_FoodCourt_Q3 + 1.5 * test_FoodCourt_IQR
# 将检测到的异常值替换为边界值
test_data['FoodCourt'] = np.clip(test_data['FoodCourt'], test_FoodCourt_lower_bound, test_FoodCourt_upper_bound)








train_ShoppingMall_Q1 = train_data['ShoppingMall'].quantile(0.25)
train_ShoppingMall_Q3 = train_data['ShoppingMall'].quantile(0.75)
train_ShoppingMall_IQR = train_ShoppingMall_Q1 - train_ShoppingMall_Q3
train_ShoppingMall_lower_bound = train_ShoppingMall_Q1 - 1.5 * train_ShoppingMall_IQR
train_ShoppingMall_upper_bound = train_ShoppingMall_Q3 + 1.5 * train_ShoppingMall_IQR
# 将检测到的异常值替换为边界值
train_data['ShoppingMall'] = np.clip(train_data['ShoppingMall'], train_ShoppingMall_lower_bound, train_ShoppingMall_upper_bound)





test_ShoppingMall_Q1 = test_data['ShoppingMall'].quantile(0.25)
test_ShoppingMall_Q3 = test_data['ShoppingMall'].quantile(0.75)
test_ShoppingMall_IQR = test_ShoppingMall_Q1 - test_ShoppingMall_Q3
test_ShoppingMall_lower_bound = test_ShoppingMall_Q1 - 1.5 * test_ShoppingMall_IQR
test_ShoppingMall_upper_bound = test_ShoppingMall_Q3 + 1.5 * test_ShoppingMall_IQR
# 将检测到的异常值替换为边界值
test_data['ShoppingMall'] = np.clip(test_data['ShoppingMall'], test_ShoppingMall_lower_bound, test_ShoppingMall_upper_bound)








train_Spa_Q1 = train_data['Spa'].quantile(0.25)
train_Spa_Q3 = train_data['Spa'].quantile(0.75)
train_Spa_IQR = train_Spa_Q1 - train_Spa_Q3
train_Spa_lower_bound = train_Spa_Q1 - 1.5 * train_Spa_IQR
train_Spa_upper_bound = train_Spa_Q3 + 1.5 * train_Spa_IQR
# 将检测到的异常值替换为边界值
train_data['Spa'] = np.clip(train_data['Spa'], train_Spa_lower_bound, train_Spa_upper_bound)





test_Spa_Q1 = test_data['Spa'].quantile(0.25)
test_Spa_Q3 = test_data['Spa'].quantile(0.75)
test_Spa_IQR = test_Spa_Q1 - test_Spa_Q3
test_Spa_lower_bound = test_Spa_Q1 - 1.5 * test_Spa_IQR
test_Spa_upper_bound = test_Spa_Q3 + 1.5 * test_Spa_IQR
# 将检测到的异常值替换为边界值
test_data['Spa'] = np.clip(test_data['Spa'], test_Spa_lower_bound, test_Spa_upper_bound)








# 检查 VRDeck 属性是否有异常值
train_VRDeck_Q1 = train_data['VRDeck'].quantile(0.25)
train_VRDeck_Q3 = train_data['VRDeck'].quantile(0.75)
train_VRDeck_IQR = train_VRDeck_Q1 - train_VRDeck_Q3
train_VRDeck_lower_bound = train_VRDeck_Q1 - 1.5 * train_VRDeck_IQR
train_VRDeck_upper_bound = train_VRDeck_Q3 + 1.5 * train_VRDeck_IQR
# 将检测到的异常值替换为边界值
train_data['VRDeck'] = np.clip(train_data['VRDeck'], train_VRDeck_lower_bound, train_VRDeck_upper_bound)





test_VRDeck_Q1 = test_data['VRDeck'].quantile(0.25)
test_VRDeck_Q3 = test_data['VRDeck'].quantile(0.75)
test_VRDeck_IQR = test_VRDeck_Q1 - test_VRDeck_Q3
test_VRDeck_lower_bound = test_VRDeck_Q1 - 1.5 * test_VRDeck_IQR
test_VRDeck_upper_bound = test_VRDeck_Q3 + 1.5 * test_VRDeck_IQR
# 将检测到的异常值替换为边界值
test_data['VRDeck'] = np.clip(test_data['VRDeck'], test_VRDeck_lower_bound, test_VRDeck_upper_bound)





# 确保 train_data 中的标签在最后一列
col_name = 'Transported' 
last_column = train_data.pop(col_name)
train_data[col_name] = last_column

# 将所有 bool类型的属性转化为 int 类型
train_bool_columns = train_data.select_dtypes(include='bool').columns
test_bool_columns = test_data.select_dtypes(include='bool').columns
train_data[train_bool_columns] = train_data[train_bool_columns].map(lambda x: 1 if x else -1)
test_data[test_bool_columns] = test_data[test_bool_columns].map(lambda x: 1 if x else -1)

# 找出非 bool 值列
train_non_bool_columns = train_data.columns.difference(train_bool_columns)
test_non_bool_columns = test_data.columns.difference(test_bool_columns)
# 对非bool值标准化
train_scaler = StandardScaler()
test_scaler = StandardScaler()
train_data[train_non_bool_columns] = train_scaler.fit_transform(train_data[train_non_bool_columns])
test_data[test_non_bool_columns] = test_scaler.fit_transform(test_data[test_non_bool_columns])

print(train_data.columns)
print(test_data.columns)


train_data.to_csv('../../RefreshedData/refreshed_train.csv', index=False)
test_data.to_csv('../../RefreshedData/refreshed_test.csv', index=False)



